﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Web;

namespace UI.Nafania.Helpers
{
	public class AttributeExtention
	{
		private static Dictionary<string, Dictionary<string, List<PropertyInfo>>> _cache = new Dictionary<string, Dictionary<string, List<PropertyInfo>>>();
		private static object _lockObj = new object();



		private readonly Type _class;
		private Dictionary<string, List<PropertyInfo>> _properties = null;

		public AttributeExtention(Type @class)
		{
			if (@class == null || @class.FullName == null)
				throw new ApplicationException();

			_class = @class;
			GetMetadataTypes();
		}

		private void GetMetadataTypes()
		{
			if (_cache.ContainsKey(_class.FullName))
			{
				_properties = _cache[_class.FullName];
				return;
			}

			lock (_lockObj)
			{

				if (_cache.ContainsKey(_class.FullName))
				{
					_properties = _cache[_class.FullName];
					return;
				}

				_properties = new Dictionary<string, List<PropertyInfo>>();

				MetadataTypeAttribute[] metadataTypes =
					_class.GetCustomAttributes(typeof (MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().ToArray();

				foreach (var metadata in metadataTypes)
				{
					PropertyInfo[] properties = metadata.MetadataClassType.GetProperties();

					foreach (PropertyInfo pi in properties)
					{
						if (!_properties.ContainsKey(pi.Name))
							_properties[pi.Name] = new List<PropertyInfo>();

						_properties[pi.Name].Add(pi);
					}
				}

				_cache[_class.FullName] = _properties;
			}
		}

		public bool IsContainAttribute(PropertyInfo pi, Type attribute)
		{
			if (pi.GetCustomAttributes(attribute, true).Count() > 0)
			{
				return true;
			}

			if (_properties.ContainsKey(pi.Name))
			{
				return _properties[pi.Name].Any(x => x.GetCustomAttributes(attribute, true).Count() > 0);
			}

			return false;
		}
	}
}